package com.cby.android.base.capture

import android.graphics.Bitmap
import android.media.Image
import android.media.Image.Plane
import android.os.Build
import androidx.annotation.RequiresApi
import com.cby.util.lib.util.CbyLogUtils
import java.nio.ByteBuffer

/**
 * @description: ImageUtils
 * @author: ChenBaoYang
 * @createDate: 2022/7/21 10:49 上午
 */
object ImageUtils {

    @RequiresApi(Build.VERSION_CODES.KITKAT)
    fun imageToBitmap(image: Image): Bitmap {
        val bitmap = Bitmap.createBitmap(image.width, image.height, Bitmap.Config.ARGB_8888)
        CbyLogUtils.i("chenby", "image.planes.size = ${image.planes.size}")
        bitmap.copyPixelsFromBuffer(image.planes[0].buffer)
        image.close()
        return bitmap
    }


    @RequiresApi(Build.VERSION_CODES.KITKAT)
    fun imageConvertToBitmap(image: Image): Bitmap {
        /*将Image对象的ByteBuffer中字节数据写进Bitmap里,因为Bitmap接收的是像素格式的数据，所以需要做一些处理*/
        //获取Image的图片像素宽、高
        val width: Int = image.width
        val height: Int = image.height
        //获取Image中的ByteBuffer
        val planes: Array<Plane> = image.planes
        val buffer: ByteBuffer = planes[0].buffer
        //获取Image中每个像素的Byte数(像素间距)，这里因为是RGBA4个通道，所以每个像素的间距是4
        val pixelStride = planes[0].pixelStride
        //获取Buffer中每行像素的字节宽度rowStride
        val rowStride = planes[0].rowStride
        //因为内存对齐的缘故，所以buffer的行宽度与上面获取到的width*pixelStride会有差异
        //内存对齐的padding字节数 = Buffer行宽 - Image中图片宽度×像素间距
        val rowPadding = rowStride - pixelStride * width
        //接收ByteBuffer数据的Bitmap需要的像素宽度 = Image中图片宽度 + 内存对齐宽度/像素间距
        //每行的对应位置会填充一些无效数据
        //(其实直接写成rowStride/pixelStride也行，按步骤写只是为了让逻辑清晰)
        val tempBmp =
            Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888)
        tempBmp.copyPixelsFromBuffer(buffer)
        //释放Image，以便继续从输入Surface接收新的画面
        image.close()
        //将tempBmp中每行像素中的无效数据过滤掉
        val lastBitmap = Bitmap.createBitmap(tempBmp, 0, 0, width, height)
        //释放tempBmp
        tempBmp.recycle()
        return lastBitmap
    }
}